package com.douqu.game.battle.entity.aobject;

import com.douqu.game.battle.controller.sprite.MonsterController;
import com.douqu.game.battle.controller.sprite.PlayerController;
import com.douqu.game.battle.controller.sprite.SpriteController;
import com.douqu.game.battle.entity.BattleSkill;
import com.douqu.game.battle.util.BattleUtils;
import com.douqu.game.battle.util.MsgUtils;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.battle.AIConfig;
import com.douqu.game.core.config.challenge.WorldBossConfig;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.common.Position;
import com.douqu.game.core.config.sprite.MasterConfig;
import com.douqu.game.core.config.sprite.MasterParamConfig;
import com.douqu.game.core.e.E_Attribute;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.battle.BattleTemp;
import com.douqu.game.core.entity.battle.SpriteTemp;
import com.douqu.game.core.entity.ext.SettingInfo;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.LogUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 主将
 * Created by bean on 2017/7/27.
 */
public class BattleMasterAObject extends BattleAObject {

    private Map<Integer, BattleSkill> aiSkillMap;

    public BattleMasterAObject(SpriteController masterController, MasterConfig masterConfig, int uniqueId, int lv, int teamNo, Position position, BattleTemp historyMasterTemp)
    {
        super(masterController, masterConfig, uniqueId, teamNo, position);

        Player player = null;
        if(masterController instanceof PlayerController)
            player = ((PlayerController) masterController).getPlayer();

        if(player != null && player.invincible)
        {
            this.lv = 999999;
            this.star = 10;
            this.hp = maxHp = cacheMaxHp = 99999999;

            this.atk = new BattleAtt(99999999, 0);
            this.def = new BattleAtt(99999999, 0);
            this.cri = new BattleAtt(9999, 0);
            this.rec = new BattleAtt(9999, 0);
            this.add = new BattleAtt(9999, 0);
            this.exd = new BattleAtt(9999, 0);
            this.hit = new BattleAtt(9999, 0);
            this.eva = new BattleAtt(9999, 0);
            this.power   = new BattleAtt(999999, 0);
            this.agility = new BattleAtt(999999, 0);
            this.wisdom  = new BattleAtt(999999, 0);
            this.phyRes  = new BattleAtt(999999, 0);
            this.punRes  = new BattleAtt(999999, 0);
            this.magRes  = new BattleAtt(999999, 0);
        }
        else
        {
            if(historyMasterTemp != null)
            {
                this.lv = historyMasterTemp.getMaster().getLv();
                this.hp = cacheMaxHp = historyMasterTemp.getMaster().getHp();
                this.maxHp = historyMasterTemp.getMaster().getMaxHp();
            }
            else
            {
                this.lv = lv;

                if(masterController instanceof MonsterController)
                {
                    MasterParamConfig masterParamConfig = null;
                    if(battleController.getBattleType() == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP)
                    {
                        masterParamConfig = DataFactory.getInstance().getGameObject(DataFactory.MASTER_PARAM_KEY, ((MonsterController) masterController).getMasterLv());
                    }
                    else
                    {
                        masterParamConfig = ((MonsterController) masterController).getBattleInitConfig().getMasterParam();
                    }
                    if(masterParamConfig != null)
                    {
                        this.hp = maxHp = cacheMaxHp = Long.parseLong(masterParamConfig.getVariable(E_Attribute.HP.getMsg()));
                        if(BattleUtils.TEST_BATTLE)
                            this.hp = maxHp = cacheMaxHp = hp * BattleUtils.TEAM1_MASTER_HP_MUL;
                    }
                    else
                    {
                        LogUtils.error("怪物属性配置错误 -> " + masterConfig + " battleType -> " + battleController.getBattleType());
                    }
                }
                else
                {
                    this.hp = maxHp = cacheMaxHp = masterConfig.getAttribute(E_Attribute.HP.getCode(), lv, player!=null?player.getMasterExtraAddAttributes(E_Attribute.HP.getCode()):0);
                    if(BattleUtils.TEST_BATTLE)
                        this.hp = maxHp = cacheMaxHp = hp * BattleUtils.TEAM1_MASTER_HP_MUL;
                }
            }

            this.atk     = createBattleAtt(masterConfig, E_Attribute.ATK, lv);
            this.def     = createBattleAtt(masterConfig, E_Attribute.DEF, lv);
            this.cri     = createBattleAtt(masterConfig, E_Attribute.CRI, lv);
            this.rec     = createBattleAtt(masterConfig, E_Attribute.REC, lv);
            this.add     = createBattleAtt(masterConfig, E_Attribute.ADD, lv);
            this.exd     = createBattleAtt(masterConfig, E_Attribute.EXD, lv);
            this.hit     = createBattleAtt(masterConfig, E_Attribute.HIT, lv);
            this.eva     = createBattleAtt(masterConfig, E_Attribute.EVA, lv);
            this.power   = createBattleAtt(masterConfig, E_Attribute.POWER, lv);
            this.phyRes  = createBattleAtt(masterConfig, E_Attribute.PHY_RES, lv);
            this.agility = createBattleAtt(masterConfig, E_Attribute.AGILITY, lv);
            this.punRes  = createBattleAtt(masterConfig, E_Attribute.PUN_RES, lv);
            this.wisdom  = createBattleAtt(masterConfig, E_Attribute.WISDOM, lv);
            this.magRes  = createBattleAtt(masterConfig, E_Attribute.MAG_RES, lv);
        }

        spriteTemp = new SpriteTemp(masterConfig.id, lv, hp ,maxHp, cacheMaxHp, 0);

        this.defaultSkill = new BattleSkill(masterController, this, masterConfig.getDefaultSkill());
        this.attackSpeed = new BattleAtt(defaultSkill.getSkillConfig().cdTime, E_Attribute.ATTACK_SPEED.getMin());
        this.moveSpeed = new BattleAtt(0, E_Attribute.MOVE_SPEED.getMin());

        aiSkillMap = new ConcurrentHashMap<>();
        if(masterController instanceof MonsterController)
        {
            AIConfig aiConfig = ((MonsterController) masterController).getAiConfig();
            if(aiConfig != null)//没有AI的时候为空
            {
                if(aiConfig.timeSkillAry != null)
                {
                    for(CommonData commonData : aiConfig.timeSkillAry)
                    {
                        aiSkillMap.put(commonData.id, new BattleSkill(masterController, this, DataFactory.getInstance().getGameObject(DataFactory.SKILL_KEY, commonData.value)));
                    }
                }
            }
        }

        List<Integer> skillIds = null;
        if(masterController instanceof PlayerController)
        {
            PlayerController playerController = (PlayerController) masterController;
            SettingInfo playerSettingInfo = playerController.getPlayer().getExtInfo(SettingInfo.class);
            skillIds = playerSettingInfo.getEquipSkillIds();
        }
        else
        {
            skillIds = masterConfig.getSkills(lv);
        }

        this.skills = new BattleSkill[skillIds.size()];
        for(int i = 0; i < skills.length; i++)
        {
            skills[i] = new BattleSkill(masterController, this, DataFactory.getInstance().getGameObject(DataFactory.SKILL_KEY, skillIds.get(i)));
        }

        LogUtils.info("主将初始化 -> " + detailInfo());
    }


    private BattleAtt createBattleAtt(MasterConfig masterConfig, E_Attribute att, int lv)
    {
        int extAddValue = 0;
        long value = 0;
        if(masterController instanceof PlayerController)
        {
            Player player = ((PlayerController) masterController).getPlayer();
            extAddValue = player.getMasterExtraAddAttributes(att.getCode());
            value = masterConfig.getAttribute(att.getCode(), lv, extAddValue);
        }
        else if(masterController instanceof MonsterController)
        {
            MasterParamConfig masterParamConfig = null;
            if(battleController.getBattleType() == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_BOSS)
            {
                StableDataConfig stableDataConfig = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.BOSS_ID_OFFSET.getCode());
                int offset = stableDataConfig == null ? 0 : stableDataConfig.intValue;
                masterParamConfig = DataFactory.getInstance().getGameObject(DataFactory.MASTER_PARAM_KEY, lv + offset);
            }
            else if(battleController.getBattleType() == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_MAP)
            {
                masterParamConfig = DataFactory.getInstance().getGameObject(DataFactory.MASTER_PARAM_KEY, ((MonsterController) masterController).getMasterLv());
            }
            else
            {
                masterParamConfig = ((MonsterController) masterController).getBattleInitConfig().getMasterParam();
            }

            if(masterParamConfig != null)
            {
                value = Long.parseLong(masterParamConfig.getVariable(att.getMsg()));
            }
            else
            {
                LogUtils.error("怪物属性配置错误 -> " + masterConfig + " battleType -> " + battleController.getBattleType());
            }

            if(battleController.getBattleType() == SGCommonProto.E_BATTLE_TYPE.BATTLE_TYPE_WORLD_BOSS)
            {
                MonsterController monsterController = (MonsterController) masterController;
                WorldBossConfig bossConfig = (WorldBossConfig) monsterController.getBattleInitConfig();
                if(bossConfig != null)
                {
                    value = (long)(value * bossConfig.getExtRate(att));
                }
            }
        }
        return new BattleAtt(value, att.getMin());
    }

    @Override
    public void checkAISkill(int battleTime)
    {
        if(aiSkillMap.get(battleTime) != null)
        {
            aiSkillMap.get(battleTime).release();
        }
    }


    @Override
    public BattleSkill getReleaseSkill(long currentTime)
    {
        for(BattleSkill skill : skills)
        {
            if(skill.isCanRelease())
                return skill;
        }
        return null;
    }



    @Override
    public boolean checkDefaultSkillTarget(long currentTime)
    {
        if(isDie())
            return false;

        if(!isCanAtk())
        {
            //被眩晕了，不能发动攻击
            LogUtils.debug("被眩晕了，不能发动攻击 -> " + this);
            return false;
        }

        if(checkTypeSkill(ConstantFactory.SKILL_TYPE_CD))
        {
            LogUtils.debug("有其它技能要释放:" + uniqueId + " name:" + getName());
            return false;
        }

        if(!defaultSkill.isCanRelease(attackSpeed.getAtt()))
        {
            LogUtils.debug("CD时间没到, name:" + getName());
            return false;
        }

        if(defaultSkill.getSkillConfig().crystal > masterController.getAttachment().getCurCrystal())
        {
            LogUtils.debug("能量 不够 name:" + getName());
            return false;
        }

        checkDefaultAtk();

        //是否还在攻击范围内
        BattleAObject defaultAtkTarget = defaultSkill.getDefaultAtkTarget();
        if(defaultAtkTarget != null && !defaultAtkTarget.isDie())
        {
            if(BattleUtils.isInAtkRange(this, defaultAtkTarget, defaultSkill.getSkillConfig()))
            {
                defaultSkill.release(defaultAtkTarget);

                checkDefaultAtk();

                checkTypeSkill(ConstantFactory.SKILL_TYPE_ADEFAULT);
                return true;
            }
            else
            {
                defaultSkill.clearDefaultAtkTarget();
                return false;
            }
        }
        else
        {
            defaultAtkTarget = getDefaultSkillTarget();
            if(defaultAtkTarget != null)
            {
                MsgUtils.sendSoldierBattleStart(battleController, this, defaultAtkTarget);

                defaultSkill.setDefaultAtkTarget(defaultAtkTarget);

                defaultSkill.release(defaultAtkTarget);

                checkDefaultAtk();

                checkTypeSkill(ConstantFactory.SKILL_TYPE_ADEFAULT);
                return true;
            }
        }
        return false;


//        TwoTuple<BattleAObject,BattleAObject> targets = checkDefaultSkillTarget(masterController.getAttachment().getTargetBattleTmp().getSoldierList());
//        if(targets.getFirst() != null)
//        {
//            MsgUtils.sendSoldierBattleStart(battleController, this, targets.getFirst());
//
//            defaultSkill.setDefaultAtkTarget(targets.getFirst());
//
//            defaultSkill.release(targets.getFirst());
//
//            checkDefaultAtk();
//
//            checkTypeSkill(ConstantFactory.SKILL_TYPE_ADEFAULT);
//        }
    }


    public int getLv() {
        return lv;
    }


    @Override
    public String getName()
    {
        return "Master_" + teamNo;
    }


    @Override
    public int getUnitType()
    {
        return ConstantFactory.UNIT_TYPE_LAND;
    }



}
